/*
 * Copyright 2013 Agustina Martinez-Garcia

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package uk.ljmu.mulgaraifz.sparql;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.igfay.jfig.JFig;
import org.igfay.jfig.JFigException;

public class QueryConstants {
	private static Logger log = Logger.getLogger(QueryConstants.class);
	private static final String PROPERTY_DELIMITER = "$";
	
	//PREDEFINED QUERIES
	
	//NEW ITQL QUERIES
	public static String GET_COLLECTION_CHILDREN_ITQL;
	public static String GET_COLLECTION_CHILDREN_ITQL_QUDEX;
	/**
	 * Obtain ID and DATASTREAM NAME of all the object within a particular namespace that present and Inline XML
	 * or RDF datastream
	 */
	public static String LOOP_GET_COLLECTIONS;
	/**
	 * Obtain ID and DATASTREAM NAME of all the object within a particular namespace that present and Inline XML
	 * or RDF datastream
	 */
	public static String LOOP_GET_IDS_BY_NAMESPACE;
	
	/**
	 * Obtain ID and DATASTREAM NAME of all the object within a particular collection that present and Inline XML
	 * or RDF datastream
	 */
	public static String LOOP_GET_IDS_BY_COLLECTION;
	
	/**
	 * GETS ID and DATASTREAM ID and DS names of a particular object that presents RDF or XML inline datastream.
	 */
	public static String LOOP_GET_IDS_BY_IDENTIFIER;
	
	/**
	 * Obtain the IDs and DS names of all the objects that present Inline XML or RDF datastreams
	 */
	public static String LOOP_GET_IDS_ALL_OBJECTS;
	
	/**
	 * 
	 */
	public static String GET_RECENT_RESOURCES_BY_COLLECTION;
	
	/**
	 * Obtain the Identifiers of recently created collection specifying the initial date
	 */
	public static String GET_RECENT_COLLECTIONS;
	
	/**
	 * Obtain the Identifiers of recently created collection specifying the initial date
	 */
	public static String GET_RECENT_COLLECTIONS_TITLE;
	
	/**
	 * If the object identifier passed presents dc:type collection then returns its identifier, if not empty
	 */
	public static String IS_COLLECTION;
	
	/**
	 * Constructs an RDF record specifying the DC information for all the items of type collection
	 */
	public static String GET_COLLECTIONS;
	
	/**
	 * Selects all the identifier of the collection objects
	 */
	public static String GET_COLLECTIONS_IDS;
	
	/**
	 * Selects all the identifier of the collection objects
	 */
	public static String GET_DEMO_COLLECTIONS_IDS;
	
	/**
	 * Constructs and RDF record with Dublin Core information of objects 
	 * that are members of a particular collection specified by its ID
	 */
	public static String GET_COLLECTIONS_INFO;
	
	/**
	 * Constructs and RDF record with DC information of all the collection objects 
	 */
	public static String GET_ALL_COLLECTIONS_INFO;
	
	/**
	 * Constructs and RDF record with Dublin Core information of objects 
	 * that are members of a particular collection specified by its ID
	 */
	public static String GET_RESOURCES_INFO;
	
	/**
	 * QUERY TO OBTAIN THE CHILDREN OF ONE COLLECTION
	 */
	public static String GET_COLLECTION_CHILDREN;
	
	public static String QUDEX_GET_COLLECTION_CHILDREN;
	
	/**
	 * QUERY TO OBTAIN THE CHILDREN OF ONE COLLECTION
	 */
	public static String GET_COLLECTION_CHILDREN_TITLE;
	
	public static final String QUDEX_GET_COLLECTION_CHILDREN_TITLE;
	/**
	 * Obtain the identifier of the collections that are top level collections, in other words that 
	 * have no parent. They belong to Fedora Object Model. Covers also empty collections.
	 */
	public static String GET_ROOT_COLS;
	public static String GET_ROOT_COLS_TITLE;
	public static String GET_ROOTS_TITLE;	
	/**
	 * Constructs a RDF DC record of a particular collection
	 */
	public static String GET_COL_INFO;
	/**
	 * Get all the objects that are not collections in a given namespace
	 */
	public static String GET_OBJECTS_BY_NS;
	
	//QUDEX QUERIES
	public static String QUDEX_GET_DEPENDANT_FILES;
	/**
	 * Includes the management of Sub-collections
	 */
	public static String QUDEX_GET_DEPENDANT_FILES_SUB;
	
	public static String QUDEX_GET_FILES;
	
	static {
		StringBuilder sb = new StringBuilder();
		sb.append("select count (select ?subject1 "); 
		sb.append("from $GRAPH$ ");
		sb.append("where walk ( ");
		sb.append("?subject <info:fedora/fedora-system:def/relations-external#isMemberOfCollection> <$COL_ID$> and ?subject1 <info:fedora/fedora-system:def/relations-external#isMemberOfCollection> ?subject) ");
		sb.append(") ");
		sb.append("from $GRAPH$ ");
		sb.append("where "); 
		sb.append("?s ?p ?o ;");
		GET_COLLECTION_CHILDREN_ITQL = sb.toString();
		sb.delete(0, GET_COLLECTION_CHILDREN_ITQL.length());
		
		sb.append("select count (select ?subject1 "); 
		sb.append("from $GRAPH$ ");
		sb.append("where walk ( ");
		sb.append("?subject <info:fedora/fedora-system:def/relations-external#isPartOf> <$COL_ID$> and ?subject1 <info:fedora/fedora-system:def/relations-external#isPartOf> ?subject) ");
		sb.append(") ");
		sb.append("from $GRAPH$ ");
		sb.append("where "); 
		sb.append("?s ?p ?o ;");
		GET_COLLECTION_CHILDREN_ITQL_QUDEX = sb.toString();
		sb.delete(0, 
			GET_COLLECTION_CHILDREN_ITQL_QUDEX.length());
		
		sb.append("SELECT DISTINCT ?o FROM $GRAPH$ where { ?s <info:fedora/fedora-system:def/relations-external#isMemberOfCollection> ?o }");		
		LOOP_GET_COLLECTIONS = sb.toString();
		sb.delete(0, LOOP_GET_COLLECTIONS.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/>");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("SELECT DISTINCT ?o1 ?o ");
		sb.append("FROM $GRAPH$ WHERE ");
		sb.append("{ ");
		sb.append("?s <info:fedora/fedora-system:def/view#disseminates> ?o; "); 
		sb.append("dc:identifier ?o1. ");
		sb.append("filter regex(?o1, \"" + "$NAMESPACE$:" + ".*\", \"i\") "); 
		sb.append("?o <info:fedora/fedora-system:def/view#mimeType> ?o3. ");
		sb.append("filter( (?o3 = \"text/xml\") || (?o3 = \"application/rdf+xml\") || (?o3 = \"application/xml\") )");
		sb.append("} ");
		LOOP_GET_IDS_BY_NAMESPACE = sb.toString();
		sb.delete(0, LOOP_GET_IDS_BY_NAMESPACE.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("SELECT DISTINCT ?o1 ?o ");
		sb.append("FROM $GRAPH$ WHERE ");
		sb.append("{ ");
		sb.append("?s <info:fedora/fedora-system:def/view#disseminates> ?o; "); 
		sb.append("<dc:identifier> ?o1; ");
		sb.append("<rel:isMemberOfCollection> <$COL_ID$>. ");
		sb.append("filter (regex(str(?o1), '$COL_NS$.*')) ");
		sb.append("?o <info:fedora/fedora-system:def/view#mimeType> ?o3. ");
		sb.append("filter( (?o3 = \"text/xml\") || (?o3 = \"application/rdf+xml\") || (?o3 = \"application/xml\") )");
		sb.append("} ");
		LOOP_GET_IDS_BY_COLLECTION = sb.toString();
		sb.delete(0, LOOP_GET_IDS_BY_COLLECTION.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("SELECT DISTINCT ?o1 ?o ");
		sb.append("FROM $GRAPH$ WHERE ");
		sb.append("{ ");
		sb.append("?s <info:fedora/fedora-system:def/view#disseminates> ?o; "); 
		sb.append("<dc:identifier> \"" + "$ID$" + "\"; ");
		sb.append("<dc:identifier> ?o1. ");
		sb.append("?o <info:fedora/fedora-system:def/view#mimeType> ?o3. ");
		sb.append("filter( (?o3 = \"text/xml\") || (?o3 = \"application/rdf+xml\") || (?o3 = \"application/xml\") )");
		sb.append("} ");
		LOOP_GET_IDS_BY_IDENTIFIER = sb.toString();
		sb.delete(0, LOOP_GET_IDS_BY_IDENTIFIER.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("SELECT DISTINCT ?o1 ?o ");
		sb.append("FROM $GRAPH$ WHERE ");
		sb.append("{ ");
		sb.append("?s <info:fedora/fedora-system:def/view#disseminates> ?o; "); 
		sb.append("<dc:identifier> ?o1.");
		sb.append("?o <info:fedora/fedora-system:def/view#mimeType> ?o3. ");
		sb.append("filter( (?o3 = \"text/xml\") || (?o3 = \"application/rdf+xml\") || (?o3 = \"application/xml\") )");
		sb.append("} ");
		LOOP_GET_IDS_ALL_OBJECTS = sb.toString();
		sb.delete(0, LOOP_GET_IDS_ALL_OBJECTS.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("SELECT DISTINCT ?s ?date ?title ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("{?s <rel:isMemberOfCollection> <$COL_ID$>} UNION "); 
		sb.append("{?s <rel:isMemberOf> <$COL_ID$>} UNION ");
		sb.append("{?s <rel:isPartOf> <$COL_ID$>} ");
		sb.append("?s <info:fedora/fedora-system:def/model#createdDate> ?date. ");
		sb.append("OPTIONAL {?s <dc:title> ?title. }");
		sb.append("}");
		sb.append("ORDER BY DESC (?date) limit 5");
		GET_RECENT_RESOURCES_BY_COLLECTION = sb.toString();
		sb.delete(0, GET_RECENT_RESOURCES_BY_COLLECTION.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("SELECT ?s ?o ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("?s <rdf:type> <dcmitype:Collection>. ");
		sb.append("?s <info:fedora/fedora-system:def/model#createdDate> ?o. "); 
		sb.append("FILTER (?o >= \"$DATE$\"^^xsd:dateTime) ");
		sb.append("}");
		GET_RECENT_COLLECTIONS = sb.toString();
		sb.delete(0, GET_RECENT_COLLECTIONS.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("SELECT ?s ?o ?title ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("?s <rdf:type> <dcmitype:Collection>. ");
		sb.append("?s <info:fedora/fedora-system:def/model#createdDate> ?o. "); 
		sb.append("FILTER (?o >= \"$DATE$\"^^xsd:dateTime) ");
		sb.append("?s <dc:title> ?title ");
		sb.append("}");
		sb.append("ORDER BY DESC (?o) limit 5");
		GET_RECENT_COLLECTIONS_TITLE = sb.toString();
		sb.delete(0, GET_RECENT_COLLECTIONS_TITLE.length());
		
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/>");
		sb.append("SELECT ?s ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("?s <rdf:type> <dcmitype:Collection>. FILTER (?s = <$ID$>) ");
		sb.append("}");
		IS_COLLECTION = sb.toString();
		sb.delete(0, IS_COLLECTION.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("CONSTRUCT ");
		sb.append("{ ");
		sb.append("?s ?p ?o. ");
		sb.append("} ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append(" { ?s1 <rel:isMemberOf> ?s. } UNION { ?s1 <rel:isMemberOfCollection> ?s. } UNION { ?s <rdf:type> <dcmitype:Collection>. } ");
		sb.append("?s ?p ?o. ");
		sb.append("filter regex(str(?p), '.*dc.*')} ");
		GET_COLLECTIONS = sb.toString();
		sb.delete(0, GET_COLLECTIONS.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append(" SELECT DISTINCT ?s ?t");
		sb.append(" FROM $GRAPH$ ");
		sb.append(" WHERE");
		sb.append(" {");
		sb.append("  { ?s1 <rel:isMemberOfCollection> ?s. } UNION { ?s1 <rel:isMemberOf> ?s. } UNION { ?s <rdf:type> <dcmitype:Collection>. }");
		sb.append(" ?s <dc:identifier> ?o; <dc:title> ?t.}");
		GET_COLLECTIONS_IDS = sb.toString();
		sb.delete(0, GET_COLLECTIONS_IDS.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append(" SELECT DISTINCT ?s ?t");
		sb.append(" FROM $GRAPH$ ");
		sb.append(" WHERE");
		sb.append(" {");
		sb.append("  { ?s1 <rel:isMemberOfCollection> ?s. } UNION { ?s1 <rel:isMemberOf> ?s. } UNION { ?s <rdf:type> <dcmitype:Collection>. }");
		sb.append(" ?s <dc:identifier> ?o; <dc:title> ?t.");
		sb.append(" filter regex(?o, '.*demo.*')} ");
		GET_DEMO_COLLECTIONS_IDS = sb.toString();
		sb.delete(0, GET_DEMO_COLLECTIONS_IDS.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/>");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#>");
		sb.append("PREFIX ex: <http://www.example.org/>");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>");
		sb.append("CONSTRUCT{ ");
		sb.append("?Collection ?p ?o. }");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{");
		sb.append("{?subject <rel:isMemberOfCollection> ?Collection.}");
		sb.append("UNION");
		sb.append("{?subject <rel:isPartOf> ?Collection.}");
		sb.append("filter regex(str(?Collection) , \".*$COL_ID$:.*\", \"i\")");
		sb.append(" { ?Collection ?p ?o. ");
		sb.append(" }	}");
		GET_COLLECTIONS_INFO = sb.toString();
		sb.delete(0, GET_COLLECTIONS_INFO.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("CONSTRUCT{ ");
		sb.append("?Collection ?p ?o. } ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{");
		sb.append("{?subject <rel:isMemberOfCollection> ?Collection.} ");
		sb.append("UNION ");
		sb.append("{?subject <rel:isMemberOf> ?Collection.} ");
		sb.append("UNION ");
		sb.append("{?subject <rel:isPartOf> ?Collection. ?Collection <rdf:type> <dcmitype:Collection>.} ");
		sb.append("UNION ");
		sb.append("{?Collection <rdf:type> <dcmitype:Collection>.} ");
		sb.append("{ ?Collection ?p ?o. ");
		sb.append("}}");
		GET_ALL_COLLECTIONS_INFO = sb.toString();
		sb.delete(0, GET_ALL_COLLECTIONS_INFO.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("CONSTRUCT ");
		sb.append("{?subject ?p ?o.} ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE { ");
		sb.append("{?subject <rel:isMemberOfCollection> ?Collection.} ");
		sb.append("UNION ");
		sb.append("{?subject <rel:isMemberOf> ?Collection.} ");
		sb.append("UNION ");
		sb.append("{?subject <rel:isPartOf> ?Collection.} ");
		sb.append("filter regex(str(?Collection) , \"$IDENTIFIER$\", \"i\") ");
		sb.append("{ ?subject ?p ?o. ");
		sb.append("filter (regex(str(?p), \".*dc.*\", \"i\"))");
		sb.append("  } }");
		GET_RESOURCES_INFO = sb.toString();
		sb.delete(0, GET_RESOURCES_INFO.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("SELECT ?s1 ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("{ ?s1 <rel:isMemberOfCollection> <$COLLECTION_ID$>.} UNION {?s1 <rel:isMemberOf> <$COLLECTION_ID$>.} ");
		sb.append("UNION { ?s1 <rel:isPartOf> <$COLLECTION_ID$>; <rdf:type> <dcmitype:Collection>.}} ");
		GET_COLLECTION_CHILDREN = sb.toString();
		sb.delete(0, GET_COLLECTION_CHILDREN.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("SELECT ?s1 ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ?s1 <rel:isPartOf> <$COLLECTION_ID$>. FILTER regex(str(?s1), \".*qudex:.*\", \"i\").}");
		QUDEX_GET_COLLECTION_CHILDREN = sb.toString();
		sb.delete(0, QUDEX_GET_COLLECTION_CHILDREN.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX ex: <http://www.example.org/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("SELECT DISTINCT ?s1 ?title ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("{?s1 <rel:isMemberOfCollection> <$COLLECTION_ID$>.} UNION ");
		sb.append("{?s1 <rel:isMemberOf> <$COLLECTION_ID$>.} UNION ");
		sb.append("{?s1 <rel:isPartOf> <$COLLECTION_ID$>; <rdf:type> <dcmitype:Collection>.} ");
		sb.append("?s1 <dc:title> ?title. }");
		GET_COLLECTION_CHILDREN_TITLE = sb.toString();
		sb.delete(0, GET_COLLECTION_CHILDREN_TITLE.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX ex: <http://www.example.org/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("SELECT ?s1 ?title ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("?s1 <rel:isPartOf> <$COLLECTION_ID$>. FILTER regex(str(?s1), \".*qudex:.*\", \"i\"). ");
		sb.append("?s1 <dc:title> ?title. }");
		QUDEX_GET_COLLECTION_CHILDREN_TITLE = sb.toString();
		sb.delete(0, QUDEX_GET_COLLECTION_CHILDREN_TITLE.length());
		 
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("SELECT DISTINCT ?x ?s1 ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("{ ");
		sb.append("?x <rdf:type> <dcmitype:Collection>. ");
		sb.append("optional {?s1 <rel:isMemberOfCollection> ?x.} ");
		sb.append("filter (!bound(?s1)) ");
		sb.append("} ");
		sb.append("UNION ");
		sb.append("{ ");
		sb.append("?y <rel:isMemberOfCollection> ?s1. ");
		sb.append("optional {?s1 <rel:isMemberOfCollection> ?s2} ");
		sb.append("filter (!bound(?s2)) ");
		sb.append("} ");
		sb.append("}");
		GET_ROOT_COLS = sb.toString();
		sb.delete(0, GET_ROOT_COLS.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("SELECT DISTINCT ?x ?s1 ?t1 ?t2 ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("{ ");
		sb.append("?x <rdf:type> <dcmitype:Collection>. ");
		sb.append("optional {?s1 <rel:isMemberOfCollection> ?x.} ");
		sb.append("filter (!bound(?s1)) ");
		sb.append("?x <dc:title> ?t1. ");
		sb.append("} ");
		sb.append("UNION ");
		sb.append("{ ");
		sb.append("?y <rel:isMemberOfCollection> ?s1. ");
		sb.append("optional {?s1 <rel:isMemberOfCollection> ?s2.} ");
		sb.append("filter (!bound(?s2)) ");
		sb.append("?s1 <dc:title> ?t2. ");
		sb.append("} ");
		sb.append("} ");
		GET_ROOT_COLS_TITLE = sb.toString();
		sb.delete(0, GET_ROOT_COLS_TITLE.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX dcmitype: <http://purl.org/dc/dcmitype/> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("SELECT DISTINCT ?x ?t1 ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE ");
		sb.append("{ ");
		sb.append("?x <rdf:type> <dcmitype:Collection>. ");
		sb.append("optional ");
		sb.append("{ ");
		sb.append("?x <rel:isMemberOfCollection> ?s2. ");
		sb.append("} ");
		sb.append("filter (!bound(?s2)). ");      
		sb.append("?x <dc:title> ?t1. ");
		sb.append("}");
		GET_ROOTS_TITLE = sb.toString();
		sb.delete(0, GET_ROOTS_TITLE.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/>");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("CONSTRUCT ");
		sb.append("{?subject ?p ?o.} ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE { ");
		sb.append("?subject ?p ?o. filter(regex(str(?subject) , \"$IDENTIFIER$\", \"i\") && (regex(str(?p), \".*dc.*\",\"i\") || regex(str(?p), \"http://www.w3.org/1999/02/22-rdf-syntax-ns#type\",\"i\")))");
		sb.append("}");
		GET_COL_INFO = sb.toString();
		sb.delete(0, GET_COL_INFO.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("SELECT ?subject ?o ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE {  ");
		sb.append("{?subject <rel:isMemberOfCollection> ?Collection.} ");
		sb.append("UNION ");
		sb.append("{?subject <rel:isMemberOf> ?Collection.} ");
		sb.append("filter regex(str(?Collection) , \".$NS$:*\", \"i\") ");
		sb.append("{?subject <dc:title> ?o. ");
		sb.append("}} ");
		GET_OBJECTS_BY_NS = sb.toString();
		
		sb = new StringBuilder();
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("SELECT ?o ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE {  ");
		sb.append("?subject rel:isPartOf+ <$COL_ID$>. ");
		sb.append("?subject dc:identifier ?o. ");
		sb.append("filter (regex(?o, \"qudex:.*\", \"i\")) ");
		sb.append("} ");
		QUDEX_GET_DEPENDANT_FILES = sb.toString();
		sb.delete(0, QUDEX_GET_DEPENDANT_FILES.length());
		
		sb = new StringBuilder();
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("SELECT ?o ");
		sb.append("FROM $GRAPH$ ");
		sb.append("WHERE {  ");
		sb.append("?subject <rel:isPartOf> <$COL_ID$>. ");
		sb.append("optional { <$COL_ID$> <rel:isPartOf> ?subject. }");
		sb.append("?subject <dc:identifier> ?o. ");
		sb.append("} ");
		QUDEX_GET_DEPENDANT_FILES_SUB = sb.toString();
		sb.delete(0, QUDEX_GET_DEPENDANT_FILES_SUB.length());
		
		sb.append("PREFIX dc: <http://purl.org/dc/elements/1.1/>");
		sb.append("PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ");
		sb.append("PREFIX rel: <info:fedora/fedora-system:def/relations-external#> ");
		sb.append("SELECT ?id ?title ");
		sb.append("FROM<$GRAPH$> ");
		sb.append("WHERE { ");
		sb.append("?id a <http://example.org/File>; ");
		sb.append("rel:isParOf <$COL_ID$>");
		sb.append("optional { ?id dc:title ?title. } "); 
		sb.append("}");
		QUDEX_GET_FILES = sb.toString();
		sb.delete(0,  QUDEX_GET_FILES.length());
	}
	/**
	 * 
	 * @param query
	 * @return modified Query
	 */
	public static String parseQuery(String query)
	{
		Pattern regexSubstitution;
		
		regexSubstitution = Pattern.compile("(.*?)(\\"+QueryConstants.PROPERTY_DELIMITER+")(.*?)(\\"+QueryConstants.PROPERTY_DELIMITER+")(.*?)$", Pattern.MULTILINE);
		String parameterName = null;
		String start = null;
		String rest = null;
		String replacementValue = null;
		
		// Loop through value while it has a symbolic reference
		Matcher matcher = regexSubstitution.matcher(query);
		
		while ((query.indexOf(QueryConstants.PROPERTY_DELIMITER) >= 0) && matcher.find()) {
			// Get the values that we matched in our regular expression
			start = matcher.group(1);
			parameterName = matcher.group(3);
			
			rest = matcher.group(5);
			// Get the value for the section/key that we are referencing
			
			try {
				replacementValue = JFig.getInstance().getValue("mulgaraServer", parameterName);
			} catch (JFigException e) {
				log.error("Error", e);
			}
			
			// Substitute the reference with the new value.
			if (replacementValue != null)
				query = start + replacementValue + rest;
			
			matcher = regexSubstitution.matcher(query);
			
		}
		
		return query;
	}
	
	/**
	 * 
	 * @param query
	 * @param paramElemName parameter name to find in the query
	 * @param parameterValue value of the wildcard to find in the query
	 * @return modified Query
	 */
	public static String parseQuery(String query, String paramElemName, String parameterValue)
	{
		Pattern regexSubstitution;
		
		regexSubstitution = Pattern.compile("(.*?)(\\"+QueryConstants.PROPERTY_DELIMITER+")(.*?)(\\"+QueryConstants.PROPERTY_DELIMITER+")(.*?)$", Pattern.MULTILINE);
		String parameterName = null;
		String start = null;
		String rest = null;
		String replacementValue = null;
		
		// Loop through value while it has a symbolic reference
		Matcher matcher = regexSubstitution.matcher(query.trim());
		String previousStart = "";
		boolean isRest = false;
		while ((query.indexOf(QueryConstants.PROPERTY_DELIMITER) >= 0) && matcher.find()) {
			// Get the values that we matched in our regular expression
			if (isRest) {
				isRest = false;
				start = previousStart + matcher.group(1);
			}
			else start =  matcher.group(1);
			parameterName = matcher.group(3);
			
			rest = matcher.group(5);
			if (!parameterName.equalsIgnoreCase(paramElemName)) {
				previousStart = start + "$" + parameterName + "$";
				isRest = true;
				matcher = regexSubstitution.matcher(rest);
				continue;
			}
			// Get the value for the section/key that we are referencing
			
			replacementValue = parameterValue;
			
			// Substitute the reference with the new value.
			if (replacementValue != null)
				query = start + replacementValue + rest;
			
			matcher = regexSubstitution.matcher(query);
		}
		
		return query;
	}
}
